type Options = {
  target: any;
  cursor?:
    | 'move'
    | 'ew-resize'
    | 'ns-resize'
    | 'nwse-resize'
    | 'nesw-resize'
    | 'col-resize'
    | 'row-resize';
  default: () => { x: number; y: number };
  updata: (p: { x: number; y: number }) => void;
};
type Position = { x: number; y: number };
import { onUnmounted, onMounted, watch, isRef } from 'vue';

const div = document.createElement('div');
div.className = 'event-mask';
div.style.display = 'none';
document.body.appendChild(div);

export default function (options: Options) {
  let startPoint: Position = { x: 0, y: 0 };
  let startEvent: MouseEvent;
  const moveStart = (e: MouseEvent) => {
    startEvent = e;
    div.style.display = 'block';
    document.body.style.cursor = options.cursor || 'ew-resize';
    startPoint = options.default();
    window.addEventListener('mouseup', moveEnd, true);
    window.addEventListener('mousemove', moveing, { passive: true, capture: true });
  };
  const moveing = (e: MouseEvent) => {
    const { x, y } = startPoint;
    const { clientX, clientY } = startEvent;
    options.updata({ x: x + e.clientX - clientX, y: y + e.clientY - clientY });
  };
  const moveEnd = e => {
    div.style.display = 'none';
    document.body.style.cursor = 'default';
    window.removeEventListener('mouseup', moveEnd, true);
    window.removeEventListener('mousemove', moveing, true);
    const { x, y } = startPoint;
    const { clientX, clientY } = startEvent;
    options.updata({ x: x + e.clientX - clientX, y: y + e.clientY - clientY });
  };
  const addEvent = target => {
    if (isRef(target) && target.value instanceof HTMLElement) {
      target.value.addEventListener('mousedown', moveStart);
    } else if (target instanceof HTMLElement) {
      target.addEventListener('mousedown', moveStart);
    } else if (typeof target === 'string') {
      const element = document.querySelector(target);
      if (element instanceof HTMLElement) {
        element.addEventListener('mousedown', moveStart);
      }
    }
  };
  onUnmounted(() => {
    window.removeEventListener('mouseup', moveEnd, true);
    window.removeEventListener('mousemove', moveing, true);
  });
  onMounted(() => {
    addEvent(options.target);
  });
  watch(
    () => options.target,
    () => {
      addEvent(options.target);
    },
    { deep: true }
  );
}
